package com.imooc.util.weixin;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imooc.dto.UserAccessToken;
import com.imooc.dto.WechatUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.URL;
import java.util.Properties;

/**
 * 主要用来提交https请求给微信获取用户信息
 * @author
 * @create 2018-08-10 16:15
 **/
public class WechatUtil {
    private static Logger log = LoggerFactory.getLogger(WechatUtil.class);

    public static void getCode() throws UnsupportedEncodingException {
        // String codeUrl =
        // "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri="
        // + URLEncoder.encode("www.cityrun.com", "utf-8")
        // +
        // "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
    }

    /**
     * 获取UserAccessToken实体类
     * @param code
     * @return
     * @throws IOException
     */
    public static UserAccessToken getUserAccessToken(String code)
            throws IOException {
       //测试号信息里的appId

        String appId = "wx94a2441260ca9344";
        log.debug("appId:" + appId);
        String appsecret ="32cd15613aeac5eadc4f5b120035466d";
        log.debug("secret:" + appsecret);
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
                + appId + "&secret=" + appsecret + "&code=" + code
                + "&grant_type=authorization_code";
        //向相应的URL发送请求获取token json字符串
        String tokenStr = httpsRequest(url,"GET",null);
        log.debug("userAccessToken:" + tokenStr);
        UserAccessToken token = new UserAccessToken();
        ObjectMapper objectMapper = new ObjectMapper();
        try{
            //将token字符串转换为对应对象
            token = objectMapper.readValue(tokenStr, UserAccessToken.class);
        }catch(JsonParseException e){
            log.error("获取用户access Token失败：" + e.getMessage());
            e.printStackTrace();
        }catch (JsonMappingException e){
            log.error("获取用户access Token失败：" + e.getMessage());
            e.printStackTrace();
        }catch (IOException e){
            log.error("获取用户access Token失败：" + e.getMessage());
            e.printStackTrace();
        }

        if (token == null) {
            log.error("获取用户access Token失败.");
            return null;
        }
        return token;
    }


    /**
     * 发送https请求并获取结果
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式
     * @param outputStr  提交的数据
     * @return json字符串
     */
    public static String httpsRequest(String requestUrl, String requestMethod, String outputStr){
        StringBuffer buffer = new StringBuffer();

        try{
            //创建SSLContext对象,并使用我们制定的信任管理器初始化
            TrustManager[] tm = { new Myx509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            //从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(requestUrl);
            HttpsURLConnection httpsURLConn = (HttpsURLConnection) url.openConnection();
            httpsURLConn.setSSLSocketFactory(ssf);

            httpsURLConn.setDoOutput(true);
            httpsURLConn.setDoInput(true);
            httpsURLConn.setUseCaches(false);
            //设置请求方式（GET/POST）
            httpsURLConn.setRequestMethod(requestMethod);
            if ("GET".equalsIgnoreCase(requestMethod)) {
                httpsURLConn.connect();
            }

            //当有数据需要提交时
            if(null != outputStr) {
                OutputStream outputStream = httpsURLConn.getOutputStream();
                //注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            //将返回的输入流转换成字符串
            InputStream inputStream = httpsURLConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            //释放资源
            inputStream.close();
            inputStream = null;
            httpsURLConn.disconnect();
            log.debug("http buffer:" + buffer.toString());
        }catch (ConnectException e){
            log.error("Weixin server connection time out");
        }catch (Exception e){
            log.error("https request error:{}",e);
        }
        return buffer.toString();
    }

    /**
     * 获取WechatUser实体类
     * @param accessToken
     * @param openId
     * @return
     */
    public static WechatUser getUserInfo(String accessToken, String openId) {
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token="
                + accessToken + "&openid=" + openId + "&lang=zh_CN";
        //访问该URL获取用户信息json字符串
        String userStr = httpsRequest(url, "GET", null);
        log.debug("user info:" + userStr);
        WechatUser user = new WechatUser();
        ObjectMapper objectMapper = new ObjectMapper();

        try{
            //将json字符串转换成相应对象
            user = objectMapper.readValue(userStr, WechatUser.class);
        }catch(JsonParseException e){
            log.error("获取用户access Token失败：" + e.getMessage());
            e.printStackTrace();
        }catch (JsonMappingException e){
            log.error("获取用户access Token失败：" + e.getMessage());
            e.printStackTrace();
        }catch (IOException e){
            log.error("获取用户access Token失败：" + e.getMessage());
            e.printStackTrace();
        }

        if (user == null) {
            log.error("获取用户信息失败。");
            return null;
        }
        return user;
    }

    /*public static boolean validAccessToken(String accessToken, String openId) {
        String url = "https://api.weixin.qq.com/sns/auth?access_token="
                + accessToken + "&openid=" + openId;
        JSONObject jsonObject = WeixinUtil.httpsRequest(url, "GET", null);
        int errcode = jsonObject.getInt("errcode");
        if (errcode == 0) {
            return true;
        } else {
            return false;
        }
    }

    public static PersonInfo getPersonInfoFromRequest(WeiXinUser user) {
        PersonInfo personInfo = new PersonInfo();
        personInfo.setName(user.getNickName());
        personInfo.setGender(user.getSex() + "");
        personInfo.setProfileImg(user.getHeadimgurl());
        personInfo.setEnableStatus(1);
        return personInfo;
    }*/
}
